home *** CD-ROM | disk | FTP | other *** search
- // new CAMERA and STEREO support routines
- // 29/12/93 by Dave Stampe
-
-
-
- /*
- This code is part of the VR-386 project, created by Dave Stampe.
- VR-386 is a desendent of REND386, created by Dave Stampe and
- Bernie Roehl. Almost all the code has been rewritten by Dave
- Stampre for VR-386.
-
- Copyright (c) 1994 by Dave Stampe:
- May be freely used to write software for release into the public domain
- or for educational use; all commercial endeavours MUST contact Dave Stampe
- (dstampe@psych.toronto.edu) for permission to incorporate any part of
- this software or source code into their products! Usually there is no
- charge for under 50-100 items for low-cost or shareware products, and terms
- are reasonable. Any royalties are used for development, so equipment is
- often acceptable payment.
-
- ATTRIBUTION: If you use any part of this source code or the libraries
- in your projects, you must give attribution to VR-386 and Dave Stampe,
- and any other authors in your documentation, source code, and at startup
- of your program. Let's keep the freeware ball rolling!
-
- DEVELOPMENT: VR-386 is a effort to develop the process started by
- REND386, improving programmer access by rewriting the code and supplying
- a standard API. If you write improvements, add new functions rather
- than rewriting current functions. This will make it possible to
- include you improved code in the next API release. YOU can help advance
- VR-386. Comments on the API are welcome.
-
- CONTACT: dstampe@psych.toronto.edu
- */
-
-
- #include <stdio.h>
- #include <stdlib.h> /* for atol(), only for debugging! */
- #include <dos.h>
- #include <alloc.h>
-
- #include "vr_api.h"
- #include "intmath.h"
- #include "segment.h"
-
-
- #include "pcdevice.h" // last_render_time()
-
-
- /* default screen data setup */
-
- STEREO default_stereo = {
- 600 , 240, 320, 50, 600, 1*65536L , // stereo setup
- 0, 0, 319, 200, 0, 0, 0, 0, 0, 0 , // left window
- 0,0,0,0,0,0,0,0,0,0,0,0,
- 0, 0, 319, 200, 0, 0, 0, 0, 0, 0 , // right window
- 0,0,0,0,0,0,0,0,0,0,0,0 };
-
- WORD stereo_type = MONOSCOPIC;
-
- // computes the static stereo factors for camera, caches
- void compute_camera_factors(CAMERA *c)
- {
- STEREO *s = c->stereo;
- STWINDOW *sw;
- DWORD x_fixup;
- DWORD world_iod;
-
- initialize_screen_factors(c->mono);
-
- if(!c->is_stereo) return;
-
- sw = &(s->window[0]);
- c->left->x_offset = sw->xoff;
- c->left->y_offset = sw->yoff;
- c->left->orientation = sw->orientation;
-
- sw = &(s->window[1]);
- c->right->x_offset = sw->xoff;
- c->right->y_offset = sw->yoff;
- c->right->orientation = sw->orientation;
-
- c->left->zoom = c->right->zoom =
- (2*65536L * s->phys_screen_dist) / s->phys_screen_width;
-
- x_fixup = (s->phys_eye_spacing * s->phys_screen_dist * s->pixel_width ) /
- (s->phys_convergence * 2 * s->phys_screen_width);
-
- world_iod = (s->phys_eye_spacing * s->world_scaling) >> 17;
-
- sw = &(s->window[0]);
- c->left->x_offset = -sw->xoff - ((sw->orientation&XFLIP) ? -x_fixup : x_fixup) ;
- std_matrix(sw->mat, sw->rx, -sw->ry, sw->rz, -world_iod, 0, 0);
- c->left->left = sw->l;
- c->left->right = sw->r;
- c->left->top = sw->t;
- c->left->bottom = sw->b;
- c->left->orientation = sw->orientation;
- initialize_screen_factors(c->left);
-
- sw = &(s->window[1]);
- c->right->x_offset = -sw->xoff - ((sw->orientation&XFLIP) ? x_fixup : -x_fixup) ;
- std_matrix(sw->mat, sw->rx, sw->ry, sw->rz, world_iod, 0, 0);
- c->right->left = sw->l;
- c->right->right = sw->r;
- c->right->top = sw->t;
- c->right->bottom = sw->b;
- c->right->orientation = sw->orientation;
- initialize_screen_factors(c->right);
- }
-
-
-
- // sets renderer to draw a view, mono or stereo view
- // also copies segment position
- VIEW *select_camera_view(CAMERA *c, WORD which_eye)
- {
- STEREO *s = c->stereo;
- MATRIX e;
- MATRIX *m = get_seg_pmatrix(c->seg);
- VIEW *v = c->mono;
-
- matrix_view_factors(c->mono, *m);
-
- if(c->is_stereo)
- {
- if(which_eye==LEFT_EYE)
- {
- matrix_product(*m,s->window[0].mat,e);
- matrix_view_factors(c->left,e);
- v = c->left;
- }
- else
- {
- matrix_product(*m,s->window[1].mat,e);
- matrix_view_factors(c->right,e);
- v = c->right;
- }
- }
- render_set_view(v);
- return v;
- }
-
-
-
- static VIEW *create_view()
- {
- VIEW *v = calloc(sizeof(VIEW),1);
- if(!v) return NULL;
- v->zoom = float2scale(2.0);
- v->left = screeninfo->xmin;
- v->right = screeninfo->xmax;
- v->top = screeninfo->ymin;
- v->bottom = screeninfo->ymax;
- v->aspect = screeninfo->aspect;
- v->hither = 10L;
- v->yon = 134217728L;
- return v;
- }
-
-
- STEREO *create_new_stereo(CAMERA *c, CAMERA *template)
- {
- STEREO *sd = calloc(sizeof(STEREO),1);
- STEREO *s = &default_stereo;
-
- if(!sd) return NULL;
- if(template)
- if(template->is_stereo)
- s = template->stereo;
- *sd = *s;
- return sd;
- }
-
-
- STEREO *get_camera_stereo(CAMERA *c)
- {
- return c->stereo;
- }
-
-
- STEREO *set_camera_stereo(CAMERA *c, STEREO *s)
- {
- c->stereo = s;
- compute_camera_factors(c);
- }
-
-
- CAMERA *create_camera(BOOL is_stereo, CAMERA *template)
- {
- CAMERA *c = calloc(sizeof(CAMERA),1);
- VIEW *v = NULL;
- VIEW *vl=NULL, *vr=NULL;
-
- if(!c) return NULL;
- if(!(v=create_view())) goto free_all;
- if(template)
- {
- memcpy(c,template,sizeof(CAMERA));
- is_stereo = template->is_stereo;
- }
-
- c->is_stereo = is_stereo;
-
- if(is_stereo)
- {
- vl = create_view();
- if(!vl) goto free_all;
- vr = create_view();
- if(!vr) goto free_all;
- if(template)
- {
- memcpy(vl,&(template->left),sizeof(VIEW));
- memcpy(vr,&(template->right),sizeof(VIEW));
- }
- else
- {
- c->stereo = &default_stereo;
- }
- c->left = vl;
- c->right = vr;
- }
-
- c->mono = v;
- c->seg = new_seg(NULL);
-
- if(c->seg)
- {
- register_system_segment(c->seg);
- initialize_screen_factors(c->mono);
- if(c->is_stereo) compute_camera_factors(c);
- }
- return c;
-
- free_all: // fail: dump memory
- if(vl) free(vl);
- if(vr) free(vr);
- if(v) free(v);
- if(c) free(c);
-
- return NULL;
- }
-
-
- void destroy_camera(CAMERA *c)
- {
- if(c->is_stereo)
- {
- free(c->left);
- free(c->right);
- }
- free(c->mono);
- destroy_segment(c->seg);
- free(c);
- }
-
- // attach camera to moveable object
- void attach_camera(CAMERA *c, OBJECT *obj)
- {
- if(!is_object_moveable(obj)) return;
- attach_object(c->seg, obj, 0);
- update_object(obj);
- }
-
-
- // detach camera
- void detach_camera(CAMERA *c)
- {
- detach_object(c->seg, 1);
- update_object(c->seg);
- }
-
-
- void set_camera_pose(CAMERA *c, POSE *p)
- {
- seg_setpose(c->seg, p);
- full_update_segment(c->seg);
- }
-
-
- void get_camera_localpose(CAMERA *c, POSE *p)
- {
- seg_getpose(c->seg, p);
- }
-
- void get_camera_worldpose(CAMERA *c, POSE *p)
- {
- seg_getworldpose(c->seg, p);
- }
-
- void get_camera_matrix(CAMERA *c, MATRIX m)
- {
- matrix_copy(*get_seg_pmatrix(c->seg), m);
- }
-
- // computes coords of point in front of MONOSCOPIC camera
- void camera_point_ahead(CAMERA *c, COORD distance,
- COORD *xp, COORD *yp, COORD *zp)
- {
- MATRIX n;
-
- matrix_copy(*get_seg_pmatrix(c->seg), n);
- *xp = 0;
- *yp = 0;
- *zp = distance;
-
- matrix_point(n, xp, yp, zp);
- }
-
-
-
- void set_camera_zoom(CAMERA *c, SCALE zoom)
- {
- c->mono->zoom = zoom;
- }
-
- SCALE get_camera_zoom(CAMERA *c)
- {
- return c->mono->zoom;
- }
-
- void set_camera_window(CAMERA *c, WORD l, WORD t, WORD r, WORD b)
- {
- c->mono->left = l;
- c->mono->top = t;
- c->mono->right = r;
- c->mono->bottom = b;
- }
-
- void set_camera_hither(CAMERA *c, COORD h)
- {
- if(h<1) return;
- c->mono->hither = h;
- if(c->is_stereo)
- {
- c->left->hither = h;
- c->right->hither = h;
- }
- }
-
- COORD get_camera_hither(CAMERA *c)
- {
- return c->mono->hither;
- }
-
- void set_camera_yon(CAMERA *c, COORD y)
- {
- if(y<1 || y>530000000L) return;
- c->mono->yon = y;
- if(c->is_stereo)
- {
- c->left->yon = y;
- c->right->yon = y;
- }
- }
-
- COORD get_camera_yon(CAMERA *c)
- {
- return c->mono->yon;
- }
-
-
-
-